#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
typedef struct {
    int* data;
    int front;
    int rear;
    int k;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* newQueue=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    newQueue->data=(int*)malloc(sizeof(int)*(k+1));//+1空出一个数据位置好判断是否为满
    newQueue->front=newQueue->rear=0;//初始化指向下标0
    newQueue->k=k;//可用空间
    return newQueue;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    assert(obj);
    if(myCircularQueueIsFull(obj)) return false;

    obj->data[obj->rear]=value;
    obj->rear=(obj->rear+1)%(obj->k+1);//后移 大于实际空间k+1时取余即可回到0
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj)) return false;
    obj->front=(obj->front+1)%(obj->k+1);//后移 大于实际空间k+1时取余即可回到0
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        return obj->data[obj->front];
    }

}

int myCircularQueueRear(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        if(obj->rear==0)//前移 小于0时回到最大可用空间处 即是尾数
            return obj->data[obj->k];//k+1 -1
        else    
            return obj->data[obj->rear-1];
    }
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
    return obj->front==obj->rear; //相等则空

}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    assert(obj);
    return (obj->rear+1)%(obj->k+1)==obj->front;//下一个是front则满
}

void myCircularQueueFree(MyCircularQueue* obj) {
    assert(obj);
    if(obj->data)
    {
        free(obj->data);
        obj->front=obj->rear=0;
        obj->k=0;
    }
}
